//
//  VC9Person.swift
//  ChapterAll
//
//  Created by Kevin on 2020/4/29.
//  Copyright © 2020 Kevin. All rights reserved.
//

import UIKit
import CoreData

class VC9Person: UIViewController {
    
    lazy var tableview = { ()-> UITableView in
        let ui = UITableView(frame: view.frame, style: .plain)
        ui.delegate = self
        ui.dataSource = self
        return ui
    }()
    
    var ctx: NSManagedObjectContext!
    var frcontroller:NSFetchedResultsController<Person>!
    
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        init_item()
        init_view()
    }
}

extension VC9Person: NSFetchedResultsControllerDelegate{
    
    // 数据将要改变
    func controllerWillChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
        print("controllerWillChangeContent")
        tableview.beginUpdates()
    }
    
    // 分区数据改变时
    func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange sectionInfo: NSFetchedResultsSectionInfo, atSectionIndex sectionIndex: Int, for type: NSFetchedResultsChangeType) {
        print("sectionInfo")
        switch type {
        case .insert:
            tableview.insertSections(IndexSet.init(integer: sectionIndex), with: .fade)
        case .delete:
            tableview.deleteSections(IndexSet(integer: sectionIndex), with: .fade)
        case .move:
            break
        case .update:
            break
        default:
            break
        }
    }
    
    // 数据改变时回调的代理
    func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) {
        print("anObject")
        switch type {
        case .insert:
            tableview.insertRows(at: [newIndexPath!], with: .fade)
        case .delete:
            tableview.deleteRows(at: [indexPath!], with: .fade)
        case .update:
            tableview.reloadRows(at: [newIndexPath!], with: .fade)
        case .move:
            tableview.deleteRows(at: [indexPath!], with: .fade)
            tableview.insertRows(at: [newIndexPath!], with: .fade)
        default:
            break
        }
    }
    
    // 数据更新结束调用的代理
    func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
        print("controllerDidChangeContent")
        tableview.endUpdates()
    }
}

extension VC9Person: UITableViewDelegate,UITableViewDataSource {
    
    func numberOfSections(in tableView: UITableView) -> Int {
        return frcontroller.sections?.count ?? 0
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return frcontroller.fetchedObjects?.count ?? 0
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let model_id = "model_id"
        var cell = tableView.dequeueReusableCell(withIdentifier: model_id)
        if cell == nil {
            cell = UITableViewCell(style: .subtitle, reuseIdentifier: model_id)
        }
        let person = frcontroller.object(at: indexPath)
        cell?.textLabel?.text = person.name
        cell?.detailTextLabel?.text = String(describing: person.age)
        return cell!
    }
}

extension VC9Person {
    
    private func init_view() -> Void {
        view.addSubview(tableview)
        guard let ctx = getCtx() else {
            return
        }
        // 查询数据库内的数据
        let request = NSFetchRequest<Person>(entityName: "Person")
        // 以年龄排序
        request.sortDescriptors = [NSSortDescriptor(key: "age", ascending: true)]
        frcontroller = NSFetchedResultsController(fetchRequest: request, managedObjectContext: ctx, sectionNameKeyPath: nil, cacheName: nil)
        frcontroller.delegate = self
        try? frcontroller.performFetch()
    }
}

extension VC9Person {
    
    private func init_item() -> Void {
        let leftItem = UIBarButtonItem(title: "添加", style: .done, target: self, action: #selector(addPerson))
        navigationItem.leftBarButtonItem = leftItem
        
        let rightItem1 = UIBarButtonItem(title: "查询", style: .done, target: self, action: #selector(queryPerson))
        let rightItem2 = UIBarButtonItem(title: "删除", style: .done, target: self, action: #selector(deletePerson))
        navigationItem.rightBarButtonItems = [rightItem1,rightItem2]
    }
    
    @objc func deletePerson() -> Void {
        guard let ctx = getCtx() else {
            return
        }
        guard let entity = NSEntityDescription.entity(forEntityName: "Person", in: ctx) else {
            print("entity is nil")
            return
        }
        let request = NSFetchRequest<Person>()
        request.entity = entity
        request.includesPropertyValues = false
        
        guard let result = try? ctx.execute(request) as? NSAsynchronousFetchResult<Person> else {
            return
        }
        guard let arr = result.finalResult else {
            print("arr is nil")
            return
        }
        if arr.count > 0 {
            ctx.delete(arr.last!)
        }
    }
    
    @objc func queryPerson() -> Void {
        guard let ctx = getCtx() else {
            return
        }
        // 查询数据库内的数据
        let request = NSFetchRequest<Person>(entityName: "Person")
        // 以年龄排序
        request.sortDescriptors = [NSSortDescriptor(key: "age", ascending: true)]
        
        guard let result = try? ctx.execute(request) as? NSAsynchronousFetchResult<Person> else {
            return
        }
        print(result.finalResult?.description ?? "")
    }
    
    @objc func addPerson() -> Void {
        guard let ctx = getCtx() else {
            return
        }
        // 对象1
        let p1 = NSEntityDescription.insertNewObject(forEntityName: "Person", into: ctx) as! Person
        p1.age = 10
        p1.name = "wang10"
        // 对象2
        let p2 = NSEntityDescription.insertNewObject(forEntityName: "Person", into: ctx) as! Person
        p2.age = 11
        p2.name = "wang11"
        // 保存
        if (try? ctx.save()) != nil {
            print("保存成功")
        }
    }
    
    private func getCtx() -> NSManagedObjectContext? {
        if ctx != nil {
            return ctx
        }
        guard let url = Bundle.main.url(forResource: "PersonModel", withExtension:".momd") else {
            print("url is nil")
            return nil
        }
        guard let path = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first?.appending("/person.sqlite") else {
            print("path is nil")
            return nil
        }
        let urlPath = URL(fileURLWithPath: path)
        guard let model = NSManagedObjectModel(contentsOf: url) else {
            return nil
        }
        let psc = NSPersistentStoreCoordinator(managedObjectModel: model)
        try! psc.addPersistentStore(ofType: NSSQLiteStoreType, configurationName: nil, at: urlPath, options: nil)
        
        ctx = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType)
        ctx.persistentStoreCoordinator = psc
        return ctx
    }
}
